﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;

namespace VendingMachineLib.Coins
{
    public class CoinCollection : TypedStacks<ICoin>
    {
        public CoinCollection()
            : base(CoinDenominations.GetAll())
        {
        }

        public CoinCollection RemoveValue(int value)
        {
            var result = new CoinCollection();
            var remainingValueToExtract = value;
            foreach (var stackEntry in _stacks)
            {
                var stack = stackEntry.Value;
                while (stack.Count > 0 && stack.Peek().Value <= remainingValueToExtract)
                {
                    var coin = stack.Pop();
                    result.Add(coin);
                    remainingValueToExtract -= coin.Value;
                }
            }

            if (remainingValueToExtract > 0)
            {
                // replace any coins which may have been popped off their stacks 
                // prior to this condition arising then throw an exception
                AddRange(result);
                throw new InsufficientChangeException();
            }

            return result;
        }

        public CoinCollection Clone()
        {
            // NOTE this is not cloning the objects, only the data structures which hold them
            var result = new CoinCollection();
            foreach (var stack in _stacks)
            {
                result._stacks[stack.Key] = new Stack<ICoin>(stack.Value);
            }
            return result;
        }
    }
}
